/*
 * Copyright (C) 2010 Fred Barrie This program is free software: you can
 * redistribute it and/or modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received
 * a copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
package org.aergia.vinny.gui.view;

import java.awt.Color;
import java.awt.Font;
import java.util.ArrayList;
import java.util.Collection;

import javax.swing.JCheckBox;
import javax.swing.JPasswordField;

import org.aergia.vinny.core.ApiResult;
import org.aergia.vinny.database.pojo.VinnyRole;
import org.aergia.vinny.database.pojo.VinnyUser;
import org.aergia.vinny.gui.controller.VinnyController;
import org.aergia.vinny.gui.util.DialogUtil;
import org.aergia.vinny.gui.util.LabelPanel;
import org.aergia.vinny.gui.util.TextField;
import org.aergia.vinny.gui.view.EditorDialog.EditorPanel;
import org.aergia.vinny.util.Md5Util;

public class UserEditor extends EditorPanel {

	private static final long serialVersionUID = 1L;
	private final VinnyController controller;
	private TextField firstNameField;
	private TextField lastNameField;
	private JCheckBox modifyConfiguration;
	private JCheckBox modifyService;
	private JCheckBox modifyUser;
	private JCheckBox modifyVolunteer;
	private JPasswordField passwordField;
	private VinnyUser saveUser;
	private final VinnyUser user;
	private JCheckBox userActive;
	private TextField userNameField;

	public UserEditor(final VinnyController controller, final VinnyUser user) {
		this(controller, user, null);
	}

	/**
	 * @param controller
	 * @param volunteer
	 */
	public UserEditor(final VinnyController controller, final VinnyUser user, final VinnyUser volunteer) {
		this.controller = controller;
		this.saveUser = volunteer;
		this.user = user;
		this.initComponents();
	}

	@Override
	public String getTitle() {
		return "User Editor";
	}

	public VinnyUser getUser() {
		return this.saveUser;
	}

	@Override
	public boolean saveAction() {

		if (!this.verify()) {
			return false;
		}

		if (this.saveUser == null) {
			this.saveUser = new VinnyUser();
		}

		this.saveUser.setActive(this.userActive.isSelected());
		this.saveUser.setFirstName(this.firstNameField.getText());
		this.saveUser.setLastName(this.lastNameField.getText());
		this.saveUser.setUserName(this.userNameField.getText());

		final String password = new String(this.passwordField.getPassword());
		if ((this.saveUser.getPassword() == null) || !this.saveUser.getPassword().equals(password)) {
			this.saveUser.setPassword(Md5Util.encode(password));
		}

		final Collection<VinnyRole> roles = new ArrayList<VinnyRole>();
		if (this.modifyConfiguration.isSelected()) {
			roles.add(this.controller.getRole(VinnyRole.MODIFY_CONFIGURATION));
		}
		if (this.modifyService.isSelected()) {
			roles.add(this.controller.getRole(VinnyRole.MODIFY_SERVICE));
		}
		if (this.modifyUser.isSelected()) {
			roles.add(this.controller.getRole(VinnyRole.MODIFY_USER));
		}
		if (this.modifyVolunteer.isSelected()) {
			roles.add(this.controller.getRole(VinnyRole.MODIFY_VOLUNTEER));
		}
		this.saveUser.setRoles(roles);

		this.saveUser();
		return true;
	}

	private void initComponents() {

		final String userName = (this.saveUser != null) && (this.saveUser.getUserName() != null) ? this.saveUser.getUserName() : "User Name";
		final boolean adminUser = userName.equals("admin");

		this.userActive = new JCheckBox();
		this.userActive.setName("Active?");
		this.userActive.setSelected(this.saveUser != null ? this.saveUser.isActive() : true);
		this.userActive.setEnabled(!adminUser);

		this.firstNameField = new TextField();
		this.firstNameField.setName("First Name");
		this.firstNameField.setText((this.saveUser != null) ? this.saveUser.getFirstName() : "First Name");
		this.firstNameField.setEnabled(!adminUser);

		this.lastNameField = new TextField();
		this.lastNameField.setName("Last Name");
		this.lastNameField.setText(this.saveUser != null ? this.saveUser.getLastName() : "Last Name");
		this.lastNameField.setEnabled(!adminUser);

		this.userNameField = new TextField();
		this.userNameField.setName("User Name");
		this.userNameField.setText(userName);
		this.userNameField.setEnabled(!adminUser);

		this.passwordField = new JPasswordField();
		this.passwordField.setName("Password");
		this.passwordField.setText(this.saveUser != null ? this.saveUser.getPassword() : "");

		this.modifyConfiguration = new JCheckBox();
		this.modifyConfiguration.setName("Modify Configuration?");
		this.modifyConfiguration.setSelected(this.saveUser != null ? this.saveUser.inRole(VinnyRole.MODIFY_CONFIGURATION) : false);
		this.modifyConfiguration.setEnabled(!adminUser);

		this.modifyService = new JCheckBox();
		this.modifyService.setName("Modify Service?");
		this.modifyService.setSelected(this.saveUser != null ? this.saveUser.inRole(VinnyRole.MODIFY_SERVICE) : false);
		this.modifyService.setEnabled(!adminUser);

		this.modifyUser = new JCheckBox();
		this.modifyUser.setName("Modify User?");
		this.modifyUser.setSelected(this.saveUser != null ? this.saveUser.inRole(VinnyRole.MODIFY_USER) : false);
		this.modifyUser.setEnabled(!adminUser);

		this.modifyVolunteer = new JCheckBox();
		this.modifyVolunteer.setName("Modify Volunteer?");
		this.modifyVolunteer.setSelected(this.saveUser != null ? this.saveUser.inRole(VinnyRole.MODIFY_VOLUNTEER) : false);
		this.modifyVolunteer.setEnabled(!adminUser);

		this.add(new LabelPanel(new Font("Dialog", Font.PLAIN, 12), Color.black, this.userActive, this.firstNameField, this.lastNameField, this.userNameField,
				this.passwordField, this.modifyConfiguration, this.modifyService, this.modifyUser, this.modifyVolunteer));
		this.setVisible(true);
	}

	private void saveUser() {
		final ApiResult<VinnyUser> result = this.controller.saveUser(this.saveUser, this.user);
		if (!result.isError()) {
			this.saveUser = result.getResult();
		}
	}

	private boolean verify() {

		final String userName = this.userNameField.getText();
		final boolean adminUser = userName.equals("admin");

		if (!adminUser && (this.firstNameField.getText().equals("First Name") || this.firstNameField.getText().isEmpty())) {
			DialogUtil.alert(this, "Please enter the user's first name.", "Invalid first name");
			return false;
		}
		if (!adminUser && (this.lastNameField.getText().equals("Last Name") || this.lastNameField.getText().isEmpty())) {
			DialogUtil.alert(this, "Please enter the user's last name.", "Invalid last name");
			return false;
		}

		if (userName.equals("User Name") || userName.isEmpty()) {
			DialogUtil.alert(this, "Please enter the user name.", "Invalid user name");
			return false;
		}

		if ((this.saveUser == null) && this.controller.isUserNameInUse(userName)) {
			DialogUtil.alert(this, "" + userName + " is already used.  Please select another name.", "Invalid user name");
			return false;
		}

		if ((this.saveUser != null) && !this.saveUser.getUserName().equals(userName) && this.controller.isUserNameInUse(userName)) {
			DialogUtil.alert(this, "" + userName + " is already used.  Please select another name.", "Invalid user name");
			return false;
		}

		if (!this.modifyConfiguration.isSelected() && !this.modifyService.isSelected() && !this.modifyUser.isSelected() && !this.modifyVolunteer.isSelected()) {
			DialogUtil.alert(this, "The user must have one permission.", "Invalid user permissions");
			return false;
		}

		return true;
	}
}
